import random
import threading
from collections import namedtuple

from pydantic import BaseModel


class model_role_resource:
    def __init__(self, name, max_num, min_num=0):
        self.name = name
        self.current_num = max_num
        self.min_num = min_num
        self.max_num = max_num

    def reduce(self, num):
        self.current_num -= num
        if self.current_num <= self.min_num:
            self.current_num = self.min_num
        return self.current_num

    def increase(self, num):
        self.current_num += num
        if self.current_num <= self.max_num:
            self.current_num = self.max_num
        return self.current_num

    def is_full(self):
        return self.current_num >= self.max_num

    def is_low(self):
        return self.current_num <= self.min_num


class model_role(BaseModel):
    id: int
    name: str
    hp: int
    speed: float
    atk: float
    defense: float
    combo: float
    dodge: float


class role:
    def __init__(self, role_data, is_enemy):
        self.role = model_role(**role_data)
        self.current_time_line = config.battle_start_time_line
        self.is_enemy = is_enemy
        self.hp = self.role.hp

    # 更新时序
    def update_time_line(self):
        global state
        if state == "working":
            # time.sleep(.01)
            self.current_time_line = round(self.current_time_line + self.role.speed, 2)
            # print(f"{self.role.name}:{self.current_time_line}")
            if self.current_time_line >= config.battle_max_time_line and self not in current_character_list:
                current_character_list.append(self)

    def is_die(self):
        return self.hp <= 0

    # 攻击
    def attack(self, target_role):
        target_role.hit(target_role.role.atk)
        self.current_time_line = config.battle_start_time_line
        print(f"{self.role.name} 攻击了 {target_role.role.name} : {target_role.role.atk}")
        print(f"{target_role.role.name} HP {target_role.hp}")
        global state, current_character_list
        current_character_list.remove(self)
        state = 'working'

    # 闪避
    def dodge(self):
        ...

    # 被攻击
    def hit(self, atk):
        self.hp -= atk


class hero(role):
    def __init__(self, role_data):
        super().__init__(role_data, False)

    def hit(self, atk_num):
        super().hit(atk_num)
        global heroes
        if self.is_die():
            heroes.remove(self)
        if len(heroes) <= 0:
            global state
            state = "result"


class enemy(role):
    def __init__(self, role_data):
        super().__init__(role_data, True)

    def hit(self, atk_num):
        super().hit(atk_num)
        global enemies
        if self.is_die():
            enemies.remove(self)
        if len(enemies) <= 0:
            global state
            state = "result"


config = namedtuple('config', ["battle_min_time_line", "battle_max_time_line", "battle_start_time_line"]) \
    (-500.00, 1000.00, 0.00)

heroes: list[role] = [hero({
    "id": 1,
    "name": "hero_1",
    "hp": 100,
    "speed": 3.1,
    "atk": 1,
    "defense": 1,
    "combo": 1,
    "dodge": 1,
})]
enemies: list[role] = [enemy({
    "id": 99,
    "name": "enemy_1",
    "hp": 100,
    "speed": 2.5,
    "atk": 1,
    "defense": 1,
    "combo": 1,
    "dodge": 1,
})]

current_character_list: list[role] = []

state = 'working'
status = ['working', 'attack', 'result']

game_run = True


def attack():
    target = None
    for _role in current_character_list:
        if _role.is_enemy:
            if heroes:
                target = random.sample(heroes, 1)[0]
        else:
            if enemies:
                target = random.sample(enemies, 1)[0]
        if target:
            _role.attack(target)


def result():
    global enemies, heroes, game_run
    if len(enemies) <= 0:
        print('hero win')
    if len(heroes) <= 0:
        print('enemy win')
    game_run = False


def auto_status():
    global state, game_run
    while game_run:
        if not len(current_character_list) == 0:
            state = 'attack'
            attack()
        if len(current_character_list) == 0:
            state = 'working'
        if len(enemies) == 0 or len(heroes) == 0:
            state = 'result'
            result()


def time_line():
    while game_run:
        for task in tasks:
            task()


if __name__ == '__main__':
    tasks = []
    for _role in heroes + enemies:
        tasks.append(_role.update_time_line)
    threading.Thread(target=time_line, daemon=True).start()
    auto_status()
